package com.nit.lab.vote.service.basic.impl;

import com.nit.lab.vote.dto.utils.OpResultDTO;
import com.nit.lab.vote.dto.basic.UserDTO;
import com.nit.lab.vote.dto.utils.PagingDTO;
import com.nit.lab.vote.dto.utils.TableReqDTO;
import com.nit.lab.vote.dto.utils.TableRspDTO;
import com.nit.lab.vote.entity.basic.UserEntity;
import com.nit.lab.vote.mapper.basic.UserMapper;
import com.nit.lab.vote.service.basic.UserService;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;


import java.util.List;
import java.util.Random;

@Service
public class UserServiceImpl implements UserService {

    @Autowired(required = false)
    private UserMapper userMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO addList(List<UserDTO> userDTOs) throws Exception {
        OpResultDTO op = new OpResultDTO();
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        for (UserDTO userDTO: userDTOs) {
            userDTO.createRandomPwd();
            UserEntity userEntity = mapperFactory.getMapperFacade().map(userDTO, UserEntity.class);
            userMapper.add(userEntity);
        }
        return op;
    }

    @Override
    public OpResultDTO listAll() throws Exception {
        OpResultDTO op = new OpResultDTO();
        List<UserDTO> userDTOS = userMapper.listAll();
        op.setResult(userDTOS);
        return op;
    }

    @Override
    public UserDTO loginCheck(String phone) throws Exception {
        return userMapper.getByPhone(phone);
    }

    @Override
    public UserDTO getByUserId(Long userId) throws Exception {
        return userMapper.getByUserId(userId);
    }

    @Override
    public TableRspDTO listAllJudge(TableReqDTO tableReqDTO) throws Exception {
        Long count = userMapper.countAllJudge(
                tableReqDTO.parseQueryParam("userName"),
                tableReqDTO.parseQueryParam("phone"));
        PagingDTO pagingDTO = new PagingDTO(
                tableReqDTO.getPageNo(),
                tableReqDTO.getPageSize(),
                count,
                userMapper.listAllJudge(
                        tableReqDTO.getStart(),
                        tableReqDTO.getPageSize(),
                        tableReqDTO.parseQueryParam("userName"),
                        tableReqDTO.parseQueryParam("phone"),
                        tableReqDTO.getSortField(),
                        tableReqDTO.getSortOrder()));
        return new TableRspDTO(pagingDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO addJudge(UserDTO userDTO) throws Exception {
        OpResultDTO op = new OpResultDTO();
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        userDTO.createRandomPwd();
        UserEntity userEntity = mapperFactory.getMapperFacade().map(userDTO, UserEntity.class);
        userEntity.setRoleId(2);
        op.setResult(userMapper.add(userEntity));
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO updateJudge(UserDTO userDTO) throws Exception {
        OpResultDTO op = new OpResultDTO();
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        UserEntity userEntity = mapperFactory.getMapperFacade().map(userDTO, UserEntity.class);
        op.setResult(userMapper.updateJudge(userEntity));
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO removeJudge(String userId) throws Exception {
        OpResultDTO op = new OpResultDTO();
        op.setResult(userMapper.removeJudge(userId));
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDTO phoneCheck(String phone) throws Exception {
        return userMapper.phoneCheck(phone);
    }
}
